package com.gingko.duominuo.ui.activity

import TaskLinkBottomFragment
import android.annotation.SuppressLint
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.graphics.Bitmap
import android.hardware.display.DisplayManager
import android.hardware.display.VirtualDisplay
import android.media.Image
import android.media.ImageReader
import android.media.projection.MediaProjectionManager
import android.os.Bundle
import android.util.DisplayMetrics
import android.util.Log
import android.view.View
import android.view.WindowManager
import androidx.activity.viewModels
import com.gingko.duominuo.R
import com.gingko.duominuo.data.datastore.DataStoreHelper
import com.gingko.duominuo.data.model.InjectAndInterceptVo
import com.gingko.duominuo.data.model.JobWorkVo
import com.gingko.duominuo.data.model.ReviewTaskVo
import com.gingko.duominuo.data.model.WorkOrderItemVo
import com.gingko.duominuo.data.request.Count
import com.gingko.duominuo.databinding.ActivityReviewWorkOrderBinding
import com.gingko.duominuo.ui.adapter.BrowserAdapter
import com.gingko.duominuo.ui.fragment.*
import com.gingko.duominuo.ui.widget.CommonDialog
import com.gingko.duominuo.utils.*
import com.gingko.duominuo.viewmodel.BaseViewModel
import com.gingko.duominuo.viewmodel.ReviewWorkOrderViewModel
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.delay
import kotlinx.coroutines.runBlocking
import java.io.File
import java.io.FileOutputStream


@AndroidEntryPoint
class ReviewWorkOrderActivity : BaseActivity() {
    private val mViewBinding by lazy { ActivityReviewWorkOrderBinding.inflate(layoutInflater) }
    private val mViewModel by viewModels<ReviewWorkOrderViewModel>()
    private val fragments by lazy { mutableListOf<BaseWebViewFragment>() }
    private val browserAdapter by lazy { BrowserAdapter(fragments, this) }
    private var currentIndex = 0
    private val workOrderItemVos by lazy { mutableListOf<WorkOrderItemVo>() }
    private var isUseX5Kernel = true
    private var userId: String? = null
    private val jobWorkVos by lazy { mutableListOf<JobWorkVo>() }
    private val reviewTaskVo by lazy { intent.getParcelableExtra<ReviewTaskVo>(KEY_REVIEW_INFO) }
    private val injectAndInterceptVo by lazy {
        intent.getParcelableExtra<InjectAndInterceptVo>(
            KEY_INJECT_INTERCEPT
        )
    }
    private val EVENT_SCREENSHOT = 22 //截图事件

    private var mediaProjectionManager: MediaProjectionManager? = null
    private var mImageReader: ImageReader? = null
    private var mWindowManager: WindowManager? = null
    private var mWindowWidth = 0
    private var mWindowHeight = 0
    private var mScreenDensity = 0
    private var screenShotIntent: Intent? = null
    private val TAG = "MainActivity"
    private var mBitmap: Bitmap? = null
    private var mVirtualDisplay: VirtualDisplay? = null


    override fun getContentView(): View {
        return mViewBinding.root
    }

    override fun getViewModel(): BaseViewModel {
        return mViewModel
    }

    override fun initView(savedInstanceState: Bundle?) {
        StatusBarUtil.setDarkMode(this)
        initProperties()
        window.setFlags(
            WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
            WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED
        )
        currentIndex = reviewTaskVo!!.currentIndex
        isUseX5Kernel = runBlocking {
            DataStoreHelper.isUseX5Kernel()
        }
        userId = runBlocking {
            DataStoreHelper.getUserId()
        }
        workOrderItemVos.addAll(reviewTaskVo?.orderList ?: listOf())
        val localJobWorks = mViewModel.queryJobWork(reviewTaskVo?.orderId!!)
        workOrderItemVos.forEach { workOrderItemVo ->
            val jobWorkVo = localJobWorks?.firstOrNull { it.jobId == workOrderItemVo.id } ?: let {
                JobWorkVo(
                    userId = userId,
                    workId = reviewTaskVo?.orderId,
                    jobId = workOrderItemVo.id
                ).apply {
                    val ids = mViewModel.insertJobWork(this)
                    this._id = ids[0]
                }

            }
            jobWorkVos.add(jobWorkVo)
        }
        for (position in 0 until workOrderItemVos.size) {
            addFragment(position)
        }
        mViewBinding.ivLink.singleClick {
            val extraLink = workOrderItemVos[currentIndex].data?.extra_link
            if (!extraLink.isNullOrEmpty()) {
                TaskLinkBottomFragment.newInstance(extraLink)
                    .showNow(supportFragmentManager, "linkDialog")
            }
        }
        mViewBinding.vpBrowser.offscreenPageLimit = 3
        mViewBinding.vpBrowser.adapter = browserAdapter
        mViewBinding.vpBrowser.currentItem = currentIndex
        mViewBinding.vpBrowser.isUserInputEnabled = false
        mViewModel.messageLiveData.observe(this) {
            it?.toast()
        }
        addClickListener()
        updatePageUI()

    }

    @SuppressLint("WrongConstant")
    private fun initProperties() {
        mediaProjectionManager =
            getSystemService(MEDIA_PROJECTION_SERVICE) as MediaProjectionManager
        screenShotIntent = mediaProjectionManager!!.createScreenCaptureIntent()
        mWindowManager = getSystemService(WINDOW_SERVICE) as WindowManager
        mWindowWidth = mWindowManager?.defaultDisplay?.width ?: 0
        mWindowHeight = mWindowManager?.defaultDisplay?.height ?: 0
        mImageReader = ImageReader.newInstance(mWindowWidth, mWindowHeight, 0x1, 2)
        val displayMetrics = DisplayMetrics()
        mWindowManager?.defaultDisplay?.getMetrics(displayMetrics)
        mScreenDensity = displayMetrics.densityDpi

    }

    private fun addClickListener() {
        mViewBinding.titleView.setOnMenuItemClickListener {
            val specification = reviewTaskVo?.reviewContent?.specification ?: arrayListOf()
            if (specification.isEmpty()) {
                "无审核条件信息".toast()
                return@setOnMenuItemClickListener true
            }
            ReviewConditionsFragment.newInstance(specification)
                .showNow(supportFragmentManager, "reviewConditionFragment")
            true
        }
        mViewBinding.ivAgree.singleClick {
            jobWorkVos[currentIndex].status = true
            jobWorkVos[currentIndex].reject_reason = null
            saveReviewTaskInfo()
            mViewBinding.ivAgree.isSelected = true
            mViewBinding.ivRefuse.isSelected = false
        }
        mViewBinding.ivRefuse.singleClick {
            val refuseData = reviewTaskVo?.reviewContent?.rejection ?: arrayListOf()
            if (refuseData.isEmpty()) {
                "拒绝原因获取失败".toast()
                return@singleClick
            }
            FailureReasonBottomDialogFragment.newInstance(refuseData)
                .apply {
                    callback = object : FailureReasonBottomDialogFragment.Callback {
                        override fun onConfirm(reason: String) {
                            jobWorkVos[currentIndex].status = false
                            jobWorkVos[currentIndex].reject_reason = reason
                            saveReviewTaskInfo()
                            mViewBinding.ivRefuse.isSelected = true
                            mViewBinding.ivAgree.isSelected = false
                        }
                    }
                }
                .showNow(supportFragmentManager, "rejectReasonFragment")

        }
        mViewBinding.ivRecommend.singleClick {
            it.isSelected = !it.isSelected
            jobWorkVos[currentIndex].perfect = it.isSelected
            saveReviewTaskInfo()
        }
        mViewBinding.ivList.singleClick {
            val count = Count().apply {
                val jobWorkVo = jobWorkVos[currentIndex]
                this.digg_count = jobWorkVo.digg_count
                this.share_count = jobWorkVo.share_count
                this.comment_count = jobWorkVo.comment_count
                this.click_count = jobWorkVo.click_count
                this.collect_count = jobWorkVo.collect_count
            }


            TaskReviewInfoCountFragment.newInstance(count)
                .apply {
                    callback = object : TaskReviewInfoCountFragment.Callback {
                        override fun onConfirm(count: Count) {
                            val jobWorkVo = jobWorkVos[currentIndex]
                            jobWorkVo.digg_count = count.digg_count
                            jobWorkVo.share_count = count.share_count
                            jobWorkVo.comment_count = count.comment_count
                            jobWorkVo.click_count = count.click_count
                            jobWorkVo.collect_count = count.collect_count
                            saveReviewTaskInfo()
                        }
                    }
                }
                .showNow(supportFragmentManager, "countFragment")
        }
        mViewBinding.ivScreenshot.singleClick {
            startActivityForResult(screenShotIntent, EVENT_SCREENSHOT)
        }
        mViewBinding.tvNextPage.singleClick {
            if (currentIndex != workOrderItemVos.size - 1) {
                currentIndex++
                mViewBinding.vpBrowser.currentItem = currentIndex
                mViewBinding.titleView.title = "${currentIndex + 1}/${workOrderItemVos.size}"
                fragments[mViewBinding.vpBrowser.currentItem].autoPlayer()
            }
//            fragments[mViewBinding.vpBrowser.currentItem].refresh()
            updatePageUI()
        }
        mViewBinding.tvLastPage.singleClick {
            if (currentIndex > 0) {
                currentIndex--
                mViewBinding.vpBrowser.currentItem = currentIndex
                mViewBinding.titleView.title = "${currentIndex + 1}/${workOrderItemVos.size}"
                fragments[mViewBinding.vpBrowser.currentItem].autoPlayer()
            }
//            fragments[mViewBinding.vpBrowser.currentItem].refresh()
            updatePageUI()
        }
        mViewBinding.icBack.singleClick {
            onBackPressed()
        }
        mViewBinding.tvRefresh.singleClick {
            fragments[mViewBinding.vpBrowser.currentItem].refresh()
        }
        mViewBinding.ivUser.singleClick {
            val userId = workOrderItemVos[currentIndex].data?.staff_account
            val userName = workOrderItemVos[currentIndex].data?.staff_nickname
            AuthorDialogFragment.newInstance(userId, userName)
                .showNow(supportFragmentManager, "userDialog")
        }
    }

    private fun getScreenshotFile(url: String) = if (url.endsWith("/")) {
        val url2 = url.substring(0, url.length - 2)
        File(
            imageCache,
            url2.substring(url2.lastIndexOf("/") + 1) + System.currentTimeMillis() + ".jpg"
        )
    } else {
        File(
            imageCache,
            url.substring(url.lastIndexOf("/") + 1) + System.currentTimeMillis() + ".jpg"
        )
    }

    private fun updatePageUI() {
        mViewBinding.titleView.title = "${currentIndex + 1}/${workOrderItemVos.size}"
        mViewBinding.tvNextPage.isEnabled = currentIndex != workOrderItemVos.size - 1
        mViewBinding.tvLastPage.isEnabled = currentIndex != 0
        mViewBinding.ivAgree.isSelected = jobWorkVos[currentIndex].status == true
        mViewBinding.ivRefuse.isSelected = jobWorkVos[currentIndex].status == false
        mViewBinding.ivRecommend.isSelected = jobWorkVos[currentIndex].perfect == true
        val isLinkEmpty = workOrderItemVos[currentIndex].data?.extra_link.isNullOrEmpty()
        mViewBinding.ivLink.isEnabled = !isLinkEmpty
        if (isLinkEmpty) {
            mViewBinding.ivLink.setImageResource(R.mipmap.ic_attachment_disable)
        } else {
            mViewBinding.ivLink.setImageResource(R.mipmap.ic_attachment)
        }
    }

    private fun saveReviewTaskInfo() {
        mViewModel.insertJobWork(jobWorkVos[currentIndex])
    }

    private fun addFragment(pageIndex: Int) {
        if (isUseX5Kernel) {
            fragments.add(
                X5KernelFragment.newInstance(
                    workOrderItemVos[pageIndex].data?.target_link ?: "", injectAndInterceptVo
                )
            )
        } else {
            fragments.add(
                WebViewFragment.newInstance(
                    workOrderItemVos[pageIndex].data?.target_link ?: "", injectAndInterceptVo
                )
            )
        }
    }

    override fun onDestroy() {
        setResult(Activity.RESULT_OK, null)
        super.onDestroy()
    }

    override fun onBackPressed() {
        if (jobWorkVos.any { it.status == null }) {
            CommonDialog.create()
                .setTitle("温馨提示")
                .setMessage("是否确认退出")
                .setNegativeText("取消")
                .setPositiveText("退出")
                .setPositiveClickListener(object : CommonDialog.ClickEvent {
                    override fun onClickEvent() {
                        this@ReviewWorkOrderActivity.finish()
                    }
                })
                .showNow(supportFragmentManager, "showNeedAgreeDialog")
        } else {
            super.onBackPressed()
        }
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        Log.e("whh0914", "onActivityResult...requestCode=$requestCode,resultCode=$resultCode")
        if (resultCode!=Activity.RESULT_OK){
            return
        }
        val mediaProjection = mediaProjectionManager!!.getMediaProjection(resultCode, data!!)
        mVirtualDisplay = mediaProjection.createVirtualDisplay(
            "ScreenCapture",
            mWindowWidth,
            mWindowHeight,
            mScreenDensity,
            DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
            mImageReader!!.surface,
            null,
            null
        )
        runBlocking {
            delay(400)
            if (null != mediaProjection) {
                try {
                    startCapture()
                } catch (e: Exception) {
                    e.printStackTrace()
                }
            }
        }
    }

    @Throws
    private fun startCapture() {
        val image: Image? = mImageReader?.acquireLatestImage()
        if (image == null) {
            Log.e(TAG, "image is null.")
            return
        }
        val width = image.width
        val height = image.height
        val planes = image.planes
        val buffer = planes[0].buffer
        val pixelStride = planes[0].pixelStride
        val rowStride = planes[0].rowStride
        val rowPadding = rowStride - pixelStride * width
        mBitmap =
            Bitmap.createBitmap(width + rowPadding / pixelStride, height, Bitmap.Config.ARGB_8888)
        mBitmap?.copyPixelsFromBuffer(buffer)
        mBitmap = Bitmap.createBitmap(
            mBitmap!!,
            mViewBinding.vpBrowser.x.toInt(),
            mViewBinding.vpBrowser.y.toInt(),
            mViewBinding.vpBrowser.width,
            mViewBinding.vpBrowser.height
        )
        image.close()
        stopScreenCapture()
        saveToFile()
    }

    private fun stopScreenCapture() {
        mVirtualDisplay?.release()
        mVirtualDisplay = null
    }

    private fun saveToFile() {
        if (mBitmap != null) {
            Log.e("whh0914", "屏幕截图成功!")
            try {
                val file = getScreenshotFile(
                    workOrderItemVos[currentIndex].data?.target_link ?: ""
                )
                FileOutputStream(file).use {
                    mBitmap!!.compress(Bitmap.CompressFormat.PNG, 100, it)
                    it.flush()
                }
                mViewModel.uploadImage(jobWorkVos[currentIndex], file)
            } catch (e: Exception) {
                "图片保存失败".toast()
            }
        }
    }


    companion object {
        private const val KEY_REVIEW_INFO = "reviewInfo"
        private const val KEY_INJECT_INTERCEPT = "injectAndIntercept"

        @JvmStatic
        fun getStartIntent(
            context: Context,
            reviewTaskVo: ReviewTaskVo,
            injectAndInterceptVo: InjectAndInterceptVo? = null
        ): Intent {
            return Intent(context, ReviewWorkOrderActivity::class.java)
                .putExtra(KEY_INJECT_INTERCEPT, injectAndInterceptVo)
                .putExtra(KEY_REVIEW_INFO, reviewTaskVo)
        }
    }
}